﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Media.Media3D;
using System.Windows;
using Eniux.Windows.ThreeDEngine.Helper;

namespace Eniux.Windows.ThreeDEngine.Visual3Ds
{
    /// <summary>
    /// 矩形
    /// </summary>
    public class RectangleVisual3D : HitMeshElement3D
    {
        #region 注册依赖属性

        #region Origin

        /// <summary>
        /// Origin属性
        /// </summary>
        public static readonly DependencyProperty OriginProperty = DependencyProperty.Register(
            "Origin",
            typeof(Point3D),
            typeof(RectangleVisual3D),
            new PropertyMetadata(new Point3D(0, 0, 0), GeometryChanged));

        /// <summary>
        /// 获取或设置原点
        /// </summary>
        public Point3D Origin
        {
            get { return (Point3D)GetValue(OriginProperty); }
            set { SetValue(OriginProperty, value); }
        }

        #endregion

        #region Length

        /// <summary>
        /// Length属性
        /// </summary>
        public static readonly DependencyProperty LengthProperty = DependencyProperty.Register(
            "Length", typeof(double), typeof(RectangleVisual3D), new PropertyMetadata(10.0, GeometryChanged));

        /// <summary>
        /// 获取或设置长度
        /// </summary>
        public double Length
        {
            get { return (double)GetValue(LengthProperty); }
            set { SetValue(LengthProperty, value); }
        }

        #endregion

        #region Width

        /// <summary>
        /// Width属性
        /// </summary>
        public static readonly DependencyProperty WidthProperty = DependencyProperty.Register(
            "Width", typeof(double), typeof(RectangleVisual3D), new PropertyMetadata(10.0, GeometryChanged));

        public double Width
        {
            get { return (double)GetValue(WidthProperty); }

            set { SetValue(WidthProperty, value); }
        }

        #endregion

        #region DivLength

        /// <summary>
        /// DivLength属性
        /// </summary>
        public static readonly DependencyProperty DivLengthProperty = DependencyProperty.Register(
            "DivLength", typeof(int), typeof(RectangleVisual3D), new UIPropertyMetadata(10));

        /// <summary>
        /// 获取或设置长度分段数
        /// </summary>
        public int DivLength
        {
            get { return (int)GetValue(DivLengthProperty); }
            set { SetValue(DivLengthProperty, value); }
        }
        
        #endregion

        #region DivWidth

        /// <summary>
        /// DivWidth属性
        /// </summary>
        public static readonly DependencyProperty DivWidthProperty = DependencyProperty.Register(
            "DivWidth", typeof(int), typeof(RectangleVisual3D), new UIPropertyMetadata(10));

        /// <summary>
        /// 获取或设置宽度分段数
        /// </summary>
        public int DivWidth
        {
            get { return (int)GetValue(DivWidthProperty); }
            set { SetValue(DivWidthProperty, value); }
        } 

        #endregion

        #region LengthDirection

        /// <summary>
        /// LengthDirection属性
        /// </summary>
        public static readonly DependencyProperty LengthDirectionProperty =
            DependencyProperty.Register(
                "LengthDirection",
                typeof(Vector3D),
                typeof(RectangleVisual3D),
                new PropertyMetadata(new Vector3D(1, 0, 0), GeometryChanged));

        /// <summary>
        /// 获取或设置长度方向
        /// </summary>
        public Vector3D LengthDirection
        {
            get { return (Vector3D)GetValue(LengthDirectionProperty); }
            set { SetValue(LengthDirectionProperty, value); }
        } 

        #endregion

        #region Normal

        /// <summary>
        /// 法线属性
        /// </summary>
        public static readonly DependencyProperty NormalProperty = DependencyProperty.Register(
            "Normal",
            typeof(Vector3D),
            typeof(RectangleVisual3D),
            new PropertyMetadata(new Vector3D(0, 0, 1), GeometryChanged));

        /// <summary>
        /// 获取或设置法线
        /// </summary>
        public Vector3D Normal
        {
            get { return (Vector3D)GetValue(NormalProperty); }
            set { SetValue(NormalProperty, value); }
        } 

        #endregion

        #endregion

        #region 重写方法

        protected override MeshGeometry3D Tessellate()
        {
            Vector3D u = LengthDirection;
            Vector3D w = Normal;
            Vector3D v = Vector3D.CrossProduct(w, u);
            u = Vector3D.CrossProduct(v, w);

            u.Normalize();
            v.Normalize();
            w.Normalize();

            double le = Length;
            double wi = Width;

            var pts = new Point3DCollection();
            for (int i = 0; i < DivLength; i++)
            {
                double fi = -0.5 + (double)i / (DivLength - 1);
                for (int j = 0; j < DivWidth; j++)
                {
                    double fj = -0.5 + (double)j / (DivWidth - 1);
                    pts.Add(Origin + u * le * fi + v * wi * fj);
                }
            }

            var builder = new MeshBuilder();
            builder.AddRectangularMesh(pts, DivWidth);

            return builder.ToMesh();
        }

        #endregion
    }
}
